/*
 * @Author: Await
 * @Date: 2025-04-17 15:30:15
 * @LastEditors: Await
 * @LastEditTime: 2025-04-17 15:38:37
 * @Description: iframe通信Hook
 */
import { useState, useEffect, useCallback } from 'react';
import { MessageType, IframeMessage } from '../types/editorTypes';
import { ChartConfig } from '../types/chartTypes';
import { DataSource } from '../types/dataTypes';

interface UseIframeCommParams {
    allowedOrigins?: string[];
    onDataUpdate?: (data: any[]) => void;
    onConfigUpdate?: (config: ChartConfig) => void;
    onThemeChange?: (theme: string) => void;
    onError?: (error: string) => void;
}

/**
 * iframe通信Hook
 * 用于处理编辑器与外部页面的通信
 */
export function useIframeComm({
    allowedOrigins = ['*'],
    onDataUpdate,
    onConfigUpdate,
    onThemeChange,
    onError
}: UseIframeCommParams = {}) {
    const [data, setData] = useState<any[] | null>(null);
    const [config, setConfig] = useState<ChartConfig | null>(null);
    const [theme, setTheme] = useState<string | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [isReady, setIsReady] = useState<boolean>(false);

    // 验证消息来源
    const validateOrigin = useCallback((origin: string): boolean => {
        if (allowedOrigins.includes('*')) return true;
        return allowedOrigins.includes(origin);
    }, [allowedOrigins]);

    // 向父窗口发送消息
    const sendMessage = useCallback((type: MessageType, payload: any) => {
        if (window.parent !== window) {
            const message: IframeMessage = {
                type,
                payload,
                source: 'echarts-editor',
                timestamp: Date.now()
            };
            window.parent.postMessage(message, '*');
        }
    }, []);

    // 数据更新
    const updateData = useCallback((newData: any[]) => {
        setData(newData);
        onDataUpdate?.(newData);
    }, [onDataUpdate]);

    // 配置更新
    const updateConfig = useCallback((newConfig: ChartConfig) => {
        setConfig(newConfig);
        onConfigUpdate?.(newConfig);
    }, [onConfigUpdate]);

    // 主题更新
    const updateTheme = useCallback((newTheme: string) => {
        setTheme(newTheme);
        onThemeChange?.(newTheme);
    }, [onThemeChange]);

    // 发送错误
    const reportError = useCallback((errorMessage: string) => {
        setError(errorMessage);
        onError?.(errorMessage);
        sendMessage(MessageType.ERROR, errorMessage);
    }, [onError, sendMessage]);

    // 通知准备就绪
    const notifyReady = useCallback(() => {
        sendMessage(MessageType.READY, { version: '1.0.0' });
        setIsReady(true);
    }, [sendMessage]);

    // 接收消息处理
    useEffect(() => {
        const handleMessage = (event: MessageEvent) => {
            // 验证消息来源
            if (!validateOrigin(event.origin)) {
                reportError(`未授权的消息来源: ${event.origin}`);
                return;
            }

            try {
                // 验证消息格式
                const message = event.data as IframeMessage;
                if (!message || !message.type) {
                    reportError('无效的消息格式');
                    return;
                }

                // 处理不同类型的消息
                switch (message.type) {
                    case MessageType.DATA_UPDATE:
                        if (Array.isArray(message.payload)) {
                            updateData(message.payload);
                        } else {
                            reportError('数据更新的payload必须是数组');
                        }
                        break;
                    case MessageType.CONFIG_UPDATE:
                        if (typeof message.payload === 'object' && message.payload !== null) {
                            updateConfig(message.payload as ChartConfig);
                        } else {
                            reportError('配置更新的payload必须是对象');
                        }
                        break;
                    case MessageType.THEME_CHANGE:
                        if (typeof message.payload === 'string') {
                            updateTheme(message.payload);
                        } else {
                            reportError('主题更新的payload必须是字符串');
                        }
                        break;
                    case MessageType.ERROR:
                        reportError(String(message.payload));
                        break;
                    default:
                        console.warn('未处理的消息类型:', message.type);
                }
            } catch (err) {
                reportError(`消息处理错误: ${(err as Error).message}`);
            }
        };

        // 添加消息监听
        window.addEventListener('message', handleMessage);

        // 通知准备就绪
        if (window.parent !== window) {
            notifyReady();
        }

        // 清理函数
        return () => {
            window.removeEventListener('message', handleMessage);
        };
    }, [validateOrigin, reportError, updateData, updateConfig, updateTheme, notifyReady]);

    return {
        data,
        config,
        theme,
        error,
        isReady,
        updateData,
        updateConfig,
        updateTheme,
        reportError,
        sendMessage
    };
} 